<!DOCTYPE html>
<html lang=zh-CN>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta property="og:description" content="samuel-24276的博客">
    <meta property="og:type" content="website">
    <meta name="description" content="samuel-24276的博客">
    <meta name="keyword"  content="aircloud">
    <link rel="shortcut icon" href="/myblog/img/favicon.ico">

    <title>
        
        JavaScript学习日记（2） - samuel-24276的博客 | samuel-24276&#39;s Blog
        
    </title>

    <!-- Custom CSS -->
    
<link rel="stylesheet" href="/myblog/css/aircloud.css">

    
<link rel="stylesheet" href="/myblog/css/gitment.css">

    <!--<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">-->
    <link href="//at.alicdn.com/t/font_620856_28hi1hpxx24.css" rel="stylesheet" type="text/css">
    <!-- ga & ba script hoook -->
    <script></script>
<meta name="generator" content="Hexo 7.1.1"></head>

<body>

<div class="site-nav-toggle" id="site-nav-toggle">
    <button>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
    </button>
</div>

<div class="index-about">
    <i> Like what you do, do what you like </i>
</div>

<div class="index-container">
    
    <div class="index-left">
        
<div class="nav" id="nav">
    <div class="avatar-name">
        <div class="avatar ">
            <img src="/myblog/img/avatar.jpg" />
        </div>
        <div class="name">
            <i>samuel-24276</i>
        </div>
    </div>
    <div class="contents" id="nav-content">
        <ul>
            <li >
                <a href="/myblog/">
                    <i class="iconfont icon-shouye1"></i>
                    <span>主页</span>
                </a>
            </li>
            <li >
                <a href="/myblog/tags">
                    <i class="iconfont icon-biaoqian1"></i>
                    <span>标签</span>
                </a>
            </li>
            <li >
                <a href="/myblog/archives">
                    <i class="iconfont icon-guidang2"></i>
                    <span>存档</span>
                </a>
            </li>
            <li >
                <a href="/myblog/collect/">
                    <i class="iconfont icon-shoucang1"></i>
                    <span>收藏</span>
                </a>
            </li>
            <li >
                <a href="/myblog/about/">
                    <i class="iconfont icon-guanyu2"></i>
                    <span>关于</span>
                </a>
            </li>
            
            <li>
                <a id="search">
                    <i class="iconfont icon-sousuo1"></i>
                    <span>搜索</span>
                </a>
            </li>
            
        </ul>
    </div>
    
        <div id="toc" class="toc-article">
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%87%BD%E6%95%B0"><span class="toc-text">函数</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0"><span class="toc-text">定义函数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E"><span class="toc-text">函数声明</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F"><span class="toc-text">函数表达式</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0-question"><span class="toc-text">调用函数:question:</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-text">函数作用域</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%92%8C%E5%87%BD%E6%95%B0%E5%A0%86%E6%A0%88"><span class="toc-text">作用域和函数堆栈</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%92%E5%BD%92-question"><span class="toc-text">递归:question:</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B5%8C%E5%A5%97%E5%87%BD%E6%95%B0%E5%92%8C%E9%97%AD%E5%8C%85"><span class="toc-text">嵌套函数和闭包</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BF%9D%E5%AD%98%E5%8F%98%E9%87%8F"><span class="toc-text">保存变量</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%9A%E5%B1%82%E5%B5%8C%E5%A5%97%E5%87%BD%E6%95%B0"><span class="toc-text">多层嵌套函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%91%BD%E5%90%8D%E5%86%B2%E7%AA%81"><span class="toc-text">命名冲突</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%97%AD%E5%8C%85"><span class="toc-text">闭包</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-arguments-%E5%AF%B9%E8%B1%A1"><span class="toc-text">使用 arguments 对象</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0"><span class="toc-text">函数参数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0"><span class="toc-text">默认参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0"><span class="toc-text">剩余参数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0-notebook"><span class="toc-text">箭头函数:notebook:</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9B%B4%E7%AE%80%E6%B4%81%E7%9A%84%E5%87%BD%E6%95%B0"><span class="toc-text">更简洁的函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#this-%E7%9A%84%E8%AF%8D%E6%B3%95"><span class="toc-text">this 的词法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%A2%84%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0"><span class="toc-text">预定义函数</span></a></li></ol></li></ol>
</div>
    
</div>


<div class="search-field" id="search-field">
    <div class="search-bg" id="search-bg"></div>
    <div class="search-container">
        <div class="search-input">
            <span id="esc-search"> <i class="icon-fanhui iconfont"></i></span>
            <input id="search-input"/>
            <span id="begin-search">搜索</span>
        </div>
        <div class="search-result-container" id="search-result-container">

        </div>
    </div>
</div>

        <div class="index-about-mobile">
            <i> Like what you do, do what you like </i>
        </div>
    </div>
    
    <div class="index-middle">
        <!-- Main Content -->
        


<div class="post-container">
    <div class="post-title">
        JavaScript学习日记（2）
    </div>

    <div class="post-meta">
        <span class="attr">发布于：<span>2023-04-22 10:20:46</span></span>
        
        <span class="attr">标签：/
        
        <a class="tag" href="/myblog/tags/#前端" title="前端">前端</a>
        <span>/</span>
        
        <a class="tag" href="/myblog/tags/#JS" title="JS">JS</a>
        <span>/</span>
        
        
        </span>
        <span class="attr">访问：<span id="busuanzi_value_page_pv"></span>
</span>
</span>
    </div>
    <div class="post-content no-indent">
        <h1 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h1><p>函数是 JavaScript 中的基本组件之一。一个函数是 JavaScript 过程 — 一组执行任务或计算值的语句。要使用一个函数，你必须将其定义在你希望调用它的作用域内。</p>
<p>一个 JavaScript 函数用<code>function</code>关键字定义，后面跟着函数名和圆括号。</p>
<p>查看 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions">JavaScript 函数详细参考文档</a> 了解更多。</p>
<blockquote>
<p><strong>函数表达式</strong>：匿名函数，可以被赋值给某个对象。</p>
<p><strong>函数提升</strong>（类似C++的前向声明）仅适用于函数声明，而不适用于函数表达式。</p>
<p>JS<strong>函数中参数传递</strong>：值传递和C++的值传递类似，对象传递和C++的指针、引用传递类似（结果类似，机制不清楚）。</p>
<p>递归函数就使用了堆栈：<strong>函数堆栈</strong>。</p>
<p>一个<strong>闭包</strong>是一个可以自己拥有独立的环境与变量的表达式（通常是函数），类似C++的命名空间（嵌套类更合适）。</p>
<p>由于内部函数可以访问外部函数的作用域，因此当内部函数<strong>生存周期</strong>大于外部函数时，外部函数中定义的变量和函数的生存周期将比内部函数执行时间长</p>
<p>在函数内部有一默认的arguments对象，保存可变数量的参数。</p>
<p><strong>默认参数</strong>和C++略有不同，C++默认参数后必须都有默认参数，否则编译错误；js默认参数后可以有非默认参数，只是使用时需要输入所有参数，默认参数会被覆盖，所以按C++方式使用即可。</p>
<p><strong>剩余参数</strong>和C++模板里的可变参数类似，将不确定数量的参数表示为数组，收集第N个到最后一个参数。</p>
</blockquote>
<h2 id="定义函数"><a href="#定义函数" class="headerlink" title="定义函数"></a>定义函数</h2><h3 id="函数声明"><a href="#函数声明" class="headerlink" title="函数声明"></a>函数声明</h3><p>一个<strong>函数定义</strong>（也称为<strong>函数声明</strong>，或<strong>函数语句</strong>）由一系列的<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function"><code>function</code></a>关键字组成，依次为：</p>
<ul>
<li>函数的名称。</li>
<li>函数参数列表，包围在括号中并由逗号分隔。</li>
<li>定义函数的 JavaScript 语句，用大括号<code>&#123;&#125;</code>括起来。</li>
</ul>
<p>例如，以下的代码定义了一个简单的<code>square</code>函数：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">square</span>(<span class="params">number</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> number * number;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>函数<code>square</code>使用了一个参数，叫作<code>number</code>。这个函数只有一个语句，它说明该函数将函数的参数（即<code>number</code>）自乘后返回。函数的<a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return"><code>return</code> (en-US)</a>语句确定了函数的返回值：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">return</span> number * number;</span><br></pre></td></tr></table></figure>

<p>原始参数（比如一个具体的数字）被作为<strong>值</strong>传递给函数；<strong>值被传递给函数，如果被调用函数改变了这个参数的值，这样的改变不会影响到全局或调用函数</strong>。</p>
<p><strong>如果你传递一个对象（即一个非原始值，例如<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array"><code>Array</code></a>或用户自定义的对象）作为参数，而函数改变了这个对象的属性，这样的改变对函数外部是可见的</strong>，如下面的例子所示：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">myFunc</span>(<span class="params">theObject</span>) &#123;</span><br><span class="line">  theObject.<span class="property">make</span> = <span class="string">&quot;Toyota&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> mycar = &#123;<span class="attr">make</span>: <span class="string">&quot;Honda&quot;</span>, <span class="attr">model</span>: <span class="string">&quot;Accord&quot;</span>, <span class="attr">year</span>: <span class="number">1998</span>&#125;;</span><br><span class="line"><span class="keyword">var</span> x, y;</span><br><span class="line"></span><br><span class="line">x = mycar.<span class="property">make</span>;     <span class="comment">// x 获取的值为 &quot;Honda&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="title function_">myFunc</span>(mycar);</span><br><span class="line">y = mycar.<span class="property">make</span>;     <span class="comment">// y 获取的值为 &quot;Toyota&quot;</span></span><br><span class="line">                    <span class="comment">// (make 属性被函数改变了)</span></span><br></pre></td></tr></table></figure>

<h3 id="函数表达式"><a href="#函数表达式" class="headerlink" title="函数表达式"></a>函数表达式</h3><p>虽然上面的函数声明在语法上是一个语句，但函数也可以由函数表达式创建。这样的函数可以是<strong>匿名</strong>的；它不必有一个名称。例如，函数<code>square</code>也可这样来定义：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> square = <span class="keyword">function</span>(<span class="params">number</span>) &#123; <span class="keyword">return</span> number * number; &#125;;</span><br><span class="line"><span class="keyword">var</span> x = <span class="title function_">square</span>(<span class="number">4</span>); <span class="comment">// x gets the value 16</span></span><br></pre></td></tr></table></figure>

<p>然而，函数表达式也可以提供函数名，并且可以用于在函数内部代指其本身，或者在调试器堆栈跟踪中识别该函数：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> factorial = <span class="keyword">function</span> <span class="title function_">fac</span>(<span class="params">n</span>) &#123;<span class="keyword">return</span> n&lt;<span class="number">2</span> ? <span class="number">1</span> : n*<span class="title function_">fac</span>(n-<span class="number">1</span>)&#125;;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">factorial</span>(<span class="number">3</span>));</span><br></pre></td></tr></table></figure>

<p>当将函数作为参数传递给另一个函数时，函数表达式很方便。下面的例子演示了一个叫<code>map</code>的函数如何被定义，而后使用一个表达式函数作为其第一个参数进行调用：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">map</span>(<span class="params">f,a</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> result = []; <span class="comment">// 创建一个数组</span></span><br><span class="line">  <span class="keyword">let</span> i; <span class="comment">// 声明一个值，用来循环</span></span><br><span class="line">  <span class="keyword">for</span> (i = <span class="number">0</span>; i != a.<span class="property">length</span>; i++)</span><br><span class="line">    result[i] = <span class="title function_">f</span>(a[i]);</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>下面的代码：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">map</span>(<span class="params">f, a</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> result = []; <span class="comment">// 创建一个数组</span></span><br><span class="line">  <span class="keyword">let</span> i; <span class="comment">// 声明一个值，用来循环</span></span><br><span class="line">  <span class="keyword">for</span> (i = <span class="number">0</span>; i != a.<span class="property">length</span>; i++)</span><br><span class="line">    result[i] = <span class="title function_">f</span>(a[i]);</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> f = <span class="keyword">function</span>(<span class="params">x</span>) &#123;</span><br><span class="line">   <span class="keyword">return</span> x * x * x;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> numbers = [<span class="number">0</span>,<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>,<span class="number">10</span>];</span><br><span class="line"><span class="keyword">let</span> cube = <span class="title function_">map</span>(f,numbers);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(cube);</span><br></pre></td></tr></table></figure>

<p>返回 [0, 1, 8, 125, 1000]。</p>
<p><strong>在 JavaScript 中，可以根据条件来定义一个函数</strong>。比如下面的代码，当<code>num</code> 等于 0 的时候才会定义 <code>myFunc</code> ：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myFunc;</span><br><span class="line"><span class="keyword">if</span> (num == <span class="number">0</span>)&#123;</span><br><span class="line">  myFunc = <span class="keyword">function</span>(<span class="params">theObject</span>) &#123;</span><br><span class="line">    theObject.<span class="property">make</span> = <span class="string">&quot;Toyota&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>除了上述的定义函数方法外，你也可以在运行时用 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function"><code>Function</code></a> 构造器由一个字符串来创建一个函数，很像 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval"><code>eval()</code></a> 函数。</p>
<p>当一个函数是一个对象的属性时，称之为<strong>方法</strong>。了解更多关于对象和方法的知识 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_objects">使用对象</a>。</p>
<h2 id="调用函数-question"><a href="#调用函数-question" class="headerlink" title="调用函数:question:"></a>调用函数:question:</h2><p>定义一个函数并不会自动的执行它。定义了函数仅仅是赋予函数以名称并明确函数被调用时该做些什么。<strong>调用</strong>函数才会以给定的参数真正执行这些动作。例如，一旦你定义了函数<code>square</code>，你可以如下这样调用它：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">square</span>(<span class="number">5</span>);</span><br></pre></td></tr></table></figure>

<p>上述语句通过提供参数 5 来调用函数。函数执行完它的语句会返回值 25。</p>
<p>**函数一定要处于调用它们的域中，但是函数的声明可以被提升 (出现在调用语句之后)**，如下例：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">square</span>(<span class="number">5</span>));</span><br><span class="line"><span class="comment">/* ... */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">square</span>(<span class="params">n</span>) &#123; <span class="keyword">return</span> n*n &#125;</span><br></pre></td></tr></table></figure>

<p>函数域是指函数声明时的所在的地方，或者函数在顶层被声明时指整个程序。</p>
<p><strong>备注：</strong> 只有使用如上的语法形式（即 <code>function funcName()&#123;&#125;</code>）才可以。而下面的代码是无效的。就是说，<strong>函数提升仅适用于函数声明，而不适用于函数表达式（作为匿名函数被赋值给某个对象）</strong>。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(square); <span class="comment">// square is hoisted with an initial value undefined.</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">square</span>(<span class="number">5</span>)); <span class="comment">// Uncaught TypeError: square is not a function</span></span><br><span class="line"><span class="keyword">const</span> square = <span class="keyword">function</span> (<span class="params">n</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> n * n;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>函数的参数并不局限于字符串或数字。你也可以将整个对象传递给函数。函数 <code>show_props</code>（其定义参见<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_objects#%E5%AF%B9%E8%B1%A1%E5%92%8C%E5%B1%9E%E6%80%A7">用对象编程</a>）就是一个将对象作为参数的例子。</p>
<p>函数可以被递归，就是说函数可以调用其本身。例如，下面这个函数就是用递归计算阶乘：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">factorial</span>(<span class="params">n</span>)&#123;</span><br><span class="line">  <span class="keyword">if</span> ((n == <span class="number">0</span>) || (n == <span class="number">1</span>))</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">    <span class="keyword">return</span> (n * <span class="title function_">factorial</span>(n - <span class="number">1</span>));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>你可以计算 1-5 的阶乘如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a, b, c, d, e;</span><br><span class="line"></span><br><span class="line">a = <span class="title function_">factorial</span>(<span class="number">1</span>); <span class="comment">// 1 赋值给 a</span></span><br><span class="line">b = <span class="title function_">factorial</span>(<span class="number">2</span>); <span class="comment">// 2 赋值给 b</span></span><br><span class="line">c = <span class="title function_">factorial</span>(<span class="number">3</span>); <span class="comment">// 6 赋值给 c</span></span><br><span class="line">d = <span class="title function_">factorial</span>(<span class="number">4</span>); <span class="comment">// 24 赋值给 d</span></span><br><span class="line">e = <span class="title function_">factorial</span>(<span class="number">5</span>); <span class="comment">// 120 赋值给 e</span></span><br></pre></td></tr></table></figure>

<p>还有其他的方式来调用函数。常见的一些情形是某些地方需要动态调用函数，或者函数的实参数量是变化的，或者调用函数的上下文需要指定为在运行时确定的特定对象。显然，函数本身就是对象，因此这些对象也有方法（参考<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function"><code>Function</code></a> ）。作为此中情形之一，<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply"><code>apply()</code></a>方法可以实现这些目的。:question:</p>
<h2 id="函数作用域"><a href="#函数作用域" class="headerlink" title="函数作用域"></a>函数作用域</h2><p>在函数内定义的变量不能在函数之外的任何地方访问，因为变量仅仅在该函数的域的内部有定义。相对应的，一个函数可以访问定义在其范围内的任何变量和函数。换言之，<strong>定义在全局域中的函数可以访问所有定义在全局域中的变量。在另一个函数中定义的函数也可以访问在其父函数中定义的所有变量和父函数有权访问的任何其他变量</strong>。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 下面的变量定义在全局作用域 (global scope) 中</span></span><br><span class="line"><span class="keyword">var</span> num1 = <span class="number">20</span>,</span><br><span class="line">    num2 = <span class="number">3</span>,</span><br><span class="line">    name = <span class="string">&quot;Chamahk&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 本函数定义在全局作用域</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">multiply</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num1 * num2;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">multiply</span>(); <span class="comment">// 返回 60</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 嵌套函数的例子</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getScore</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> num1 = <span class="number">2</span>,</span><br><span class="line">      num2 = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">add</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> name + <span class="string">&quot; scored &quot;</span> + (num1 + num2);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">add</span>();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">getScore</span>(); <span class="comment">// 返回 &quot;Chamahk scored 5&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="作用域和函数堆栈"><a href="#作用域和函数堆栈" class="headerlink" title="作用域和函数堆栈"></a>作用域和函数堆栈</h2><h3 id="递归-question"><a href="#递归-question" class="headerlink" title="递归:question:"></a>递归:question:</h3><p>一个函数可以指向并调用自身。有三种方法可以达到这个目的：</p>
<ol>
<li>函数名</li>
<li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/callee"><code>arguments.callee</code></a></li>
<li>作用域下的一个指向该函数的变量名</li>
</ol>
<p>例如，思考一下如下的函数定义：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> foo = <span class="keyword">function</span> <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line">   <span class="comment">// statements go here</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>在这个函数体内，以下的语句是等价的：</p>
<ol>
<li><code>bar()</code></li>
<li><code>arguments.callee()</code> <strong>（译者注：ES5 禁止在严格模式下使用此属性）</strong></li>
<li><code>foo()</code></li>
</ol>
<p>调用自身的函数我们称之为<em>递归函数</em>。在某种意义上说，递归近似于循环。两者都重复执行相同的代码，并且两者都需要一个终止条件（避免无限循环或者无限递归）。例如以下的循环：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span> (x &lt; <span class="number">10</span>) &#123; <span class="comment">// &quot;x &lt; 10&quot; 是循环条件</span></span><br><span class="line">   <span class="comment">// do stuff</span></span><br><span class="line">   x++;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>可以被转化成一个递归函数和对其的调用：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">loop</span>(<span class="params">x</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (x &gt;= <span class="number">10</span>) <span class="comment">// &quot;x &gt;= 10&quot; 是退出条件（等同于 &quot;!(x &lt; 10)&quot;）</span></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  <span class="comment">// 做些什么</span></span><br><span class="line">  <span class="title function_">loop</span>(x + <span class="number">1</span>); <span class="comment">// 递归调用</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">loop</span>(<span class="number">0</span>);</span><br></pre></td></tr></table></figure>

<p>不过，有些算法并不能简单的用迭代来实现。例如，获取树结构中所有的节点时，使用递归实现要容易得多：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">walkTree</span>(<span class="params">node</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (node == <span class="literal">null</span>) <span class="comment">//</span></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  <span class="comment">// do something with node</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; node.<span class="property">childNodes</span>.<span class="property">length</span>; i++) &#123;</span><br><span class="line">    <span class="title function_">walkTree</span>(node.<span class="property">childNodes</span>[i]);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>跟<code>loop</code>函数相比，这里每个递归调用都产生了更多的递归。</p>
<p>将递归算法转换为非递归算法是可能的，不过逻辑上通常会更加复杂，而且需要使用堆栈。事实上，<strong>递归函数就使用了堆栈：函数堆栈</strong>。</p>
<p>这种类似堆栈的行为可以在下例中看到：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">i</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (i &lt; <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;begin:&#x27;</span> + i);</span><br><span class="line">  <span class="title function_">foo</span>(i - <span class="number">1</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;end:&#x27;</span> + i);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 输出：</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// begin:3</span></span><br><span class="line"><span class="comment">// begin:2</span></span><br><span class="line"><span class="comment">// begin:1</span></span><br><span class="line"><span class="comment">// begin:0</span></span><br><span class="line"><span class="comment">// end:0</span></span><br><span class="line"><span class="comment">// end:1</span></span><br><span class="line"><span class="comment">// end:2</span></span><br><span class="line"><span class="comment">// end:3</span></span><br></pre></td></tr></table></figure>

<h3 id="嵌套函数和闭包"><a href="#嵌套函数和闭包" class="headerlink" title="嵌套函数和闭包"></a>嵌套函数和闭包</h3><p>你可以在一个函数里面嵌套另外一个函数。嵌套（内部）函数对其容器（外部）函数是私有的。它自身也形成了一个闭包。<strong>一个闭包是一个可以自己拥有独立的环境与变量的表达式（通常是函数）</strong>。</p>
<p>既然嵌套函数是一个闭包，就意味着一个嵌套函数可以”继承“容器函数的参数和变量。换句话说，内部函数包含外部函数的作用域。</p>
<p>可以总结如下：</p>
<ul>
<li>内部函数只可以在外部函数中访问。</li>
<li>内部函数形成了一个闭包：它可以访问外部函数的参数和变量，但是外部函数却不能使用它的参数和变量。</li>
</ul>
<p>下面的例子展示了嵌套函数：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">addSquares</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">square</span>(<span class="params">x</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> x * x;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">square</span>(a) + <span class="title function_">square</span>(b);</span><br><span class="line">&#125;</span><br><span class="line">a = <span class="title function_">addSquares</span>(<span class="number">2</span>, <span class="number">3</span>); <span class="comment">// returns 13</span></span><br><span class="line">b = <span class="title function_">addSquares</span>(<span class="number">3</span>, <span class="number">4</span>); <span class="comment">// returns 25</span></span><br><span class="line">c = <span class="title function_">addSquares</span>(<span class="number">4</span>, <span class="number">5</span>); <span class="comment">// returns 41</span></span><br></pre></td></tr></table></figure>

<p>由于内部函数形成了闭包，因此你可以调用外部函数并为外部函数和内部函数指定参数：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">outside</span>(<span class="params">x</span>) &#123;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">inside</span>(<span class="params">y</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> x + y;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> inside;</span><br><span class="line">&#125;</span><br><span class="line">fn_inside = <span class="title function_">outside</span>(<span class="number">3</span>); <span class="comment">// 可以这样想：给一个函数，使它的值加 3</span></span><br><span class="line">result = <span class="title function_">fn_inside</span>(<span class="number">5</span>); <span class="comment">// returns 8</span></span><br><span class="line"></span><br><span class="line">result1 = <span class="title function_">outside</span>(<span class="number">3</span>)(<span class="number">5</span>); <span class="comment">// returns 8</span></span><br></pre></td></tr></table></figure>



<h3 id="保存变量"><a href="#保存变量" class="headerlink" title="保存变量"></a>保存变量</h3><p>注意到上例中 <code>inside</code> 被返回时 <code>x</code> 是怎么被保留下来的。一个闭包必须保存它可见作用域中所有参数和变量。因为每一次调用传入的参数都可能不同，每一次对外部函数的调用实际上重新创建了一遍这个闭包。只有当返回的 <code>inside</code> 没有再被引用时，内存才会被释放。</p>
<p>这与在其他对象中存储引用没什么不同，但是通常不太明显，因为并不能直接设置引用，也不能检查它们。</p>
<h3 id="多层嵌套函数"><a href="#多层嵌套函数" class="headerlink" title="多层嵌套函数"></a>多层嵌套函数</h3><p>函数可以被多层嵌套。例如，函数 A 可以包含函数 B，函数 B 可以再包含函数 C。B 和 C 都形成了闭包，所以 B 可以访问 A，C 可以访问 B 和 A。因此，<strong>闭包可以包含多个作用域；他们递归式的包含了所有包含它的函数作用域。这个称之为<em>作用域链</em></strong>。（稍后会详细解释）</p>
<p>思考一下下面的例子：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">A</span>(<span class="params">x</span>) &#123;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">B</span>(<span class="params">y</span>) &#123;</span><br><span class="line">    <span class="keyword">function</span> <span class="title function_">C</span>(<span class="params">z</span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(x + y + z);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="title function_">C</span>(<span class="number">3</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">B</span>(<span class="number">2</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">A</span>(<span class="number">1</span>); <span class="comment">// logs 6 (1 + 2 + 3)</span></span><br></pre></td></tr></table></figure>

<p>在这个例子里面，C 可以访问 B 的 y 和 A 的 x。这是因为：</p>
<ol>
<li>B 形成了一个包含 A 的闭包，B 可以访问 A 的参数和变量</li>
<li>C 形成了一个包含 B 的闭包</li>
<li>B 包含 A，所以 C 也包含 A，C 可以访问 B 和 A 的参数和变量。换言之，C 用这个顺序链接了 B 和 A 的作用域</li>
</ol>
<p>反过来却不是这样。A 不能访问 C，因为 A 看不到 B 中的参数和变量，C 是 B 中的一个变量，所以 C 是 B 私有的。</p>
<h3 id="命名冲突"><a href="#命名冲突" class="headerlink" title="命名冲突"></a>命名冲突</h3><p><strong>当同一个闭包作用域下两个参数或者变量同名时，就会产生命名冲突。更近的作用域有更高的优先权，所以最近的优先级最高，最远的优先级最低。这就是作用域链</strong>。链的第一个元素就是最里面的作用域，最后一个元素便是最外层的作用域。</p>
<p>看以下的例子：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">outside</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> x = <span class="number">5</span>;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">inside</span>(<span class="params">x</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> x * <span class="number">2</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> inside;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">outside</span>()(<span class="number">10</span>); <span class="comment">// returns 20 instead of 10</span></span><br></pre></td></tr></table></figure>

<p>命名冲突发生在<code>return x</code>上，<code>inside</code>的参数<code>x</code>和<code>outside</code>变量<code>x</code>发生了冲突。这里的作用链域是{<code>inside</code>, <code>outside</code>, 全局对象}。因此<code>inside</code>的<code>x</code>具有最高优先权，返回了 20（<code>inside</code>的<code>x</code>）而不是 10（<code>outside</code>的<code>x</code>）。</p>
<h2 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h2><p>闭包是 JavaScript 中最强大的特性之一。JavaScript 允许函数嵌套，并且内部函数可以访问定义在外部函数中的所有变量和函数，以及外部函数能访问的所有变量和函数。</p>
<p>但是，外部函数却不能够访问定义在内部函数中的变量和函数。这给内部函数的变量提供了一定的安全性。</p>
<p>此外，<strong>由于内部函数可以访问外部函数的作用域，因此当内部函数生存周期大于外部函数时，外部函数中定义的变量和函数的生存周期将比内部函数执行时间长</strong>。当内部函数以某一种方式被任何一个外部函数作用域访问时，一个闭包就产生了。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pet = <span class="keyword">function</span>(<span class="params">name</span>) &#123;          <span class="comment">//外部函数定义了一个变量&quot;name&quot;</span></span><br><span class="line">  <span class="keyword">var</span> getName = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">//内部函数可以访问 外部函数定义的&quot;name&quot;</span></span><br><span class="line">    <span class="keyword">return</span> name;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//返回这个内部函数，从而将其暴露在外部函数作用域</span></span><br><span class="line">  <span class="keyword">return</span> getName;</span><br><span class="line">&#125;;</span><br><span class="line">myPet = <span class="title function_">pet</span>(<span class="string">&quot;Vivie&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="title function_">myPet</span>();                            <span class="comment">// 返回结果 &quot;Vivie&quot;</span></span><br></pre></td></tr></table></figure>

<p>实际上可能会比上面的代码复杂的多。在下面这种情形中，返回了一个包含可以操作外部函数的内部变量方法的对象。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> createPet = <span class="keyword">function</span>(<span class="params">name</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> sex;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">setName</span>: <span class="keyword">function</span>(<span class="params">newName</span>) &#123;</span><br><span class="line">      name = newName;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="attr">getName</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> name;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="attr">getSex</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> sex;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="attr">setSex</span>: <span class="keyword">function</span>(<span class="params">newSex</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span>(<span class="keyword">typeof</span> newSex == <span class="string">&quot;string&quot;</span></span><br><span class="line">        &amp;&amp; (newSex.<span class="title function_">toLowerCase</span>() == <span class="string">&quot;male&quot;</span> || newSex.<span class="title function_">toLowerCase</span>() == <span class="string">&quot;female&quot;</span>)) &#123;</span><br><span class="line">        sex = newSex;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> pet = <span class="title function_">createPet</span>(<span class="string">&quot;Vivie&quot;</span>);</span><br><span class="line">pet.<span class="title function_">getName</span>();                  <span class="comment">// Vivie</span></span><br><span class="line"></span><br><span class="line">pet.<span class="title function_">setName</span>(<span class="string">&quot;Oliver&quot;</span>);</span><br><span class="line">pet.<span class="title function_">setSex</span>(<span class="string">&quot;male&quot;</span>);</span><br><span class="line">pet.<span class="title function_">getSex</span>();                   <span class="comment">// male</span></span><br><span class="line">pet.<span class="title function_">getName</span>();                  <span class="comment">// Oliver</span></span><br></pre></td></tr></table></figure>

<p>在上面的代码中，外部函数的<code>name</code>变量对内嵌函数来说是可取得的，而除了通过内嵌函数本身，没有其他任何方法可以取得内嵌的变量。内嵌函数的内嵌变量就像内嵌函数的保险柜。它们会为内嵌函数保留“稳定”——而又安全——的数据参与运行。而这些内嵌函数甚至不会被分配给一个变量，或者不必一定要有名字。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> getCode = (<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> secureCode = <span class="string">&quot;0]Eal(eh&amp;2&quot;</span>;    <span class="comment">// A code we do not want outsiders to be able to modify...</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> secureCode;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="title function_">getCode</span>();    <span class="comment">// Returns the secret code</span></span><br></pre></td></tr></table></figure>

<p><strong>备注：</strong> 尽管有上述优点，使用闭包时仍然要小心避免一些陷阱。如果一个闭包的函数定义了一个和外部函数的某个变量名称相同的变量，那么这个闭包将无法引用外部函数的这个变量。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> createPet = <span class="keyword">function</span>(<span class="params">name</span>) &#123;  <span class="comment">// Outer function defines a variable called &quot;name&quot;</span></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">setName</span>: <span class="keyword">function</span>(<span class="params">name</span>) &#123;    <span class="comment">// Enclosed function also defines a variable called &quot;name&quot;</span></span><br><span class="line">      name = name;               <span class="comment">// ??? How do we access the &quot;name&quot; defined by the outer function ???</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="使用-arguments-对象"><a href="#使用-arguments-对象" class="headerlink" title="使用 arguments 对象"></a>使用 arguments 对象</h2><p>函数的实际参数会被保存在一个类似数组的 arguments 对象中。在函数内，你可以按如下方式找出传入的参数：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">arguments</span>[i]</span><br></pre></td></tr></table></figure>

<p>其中<code>i</code>是参数的序数编号（译注：数组索引），以 0 开始。所以第一个传来的参数会是<code>arguments[0]</code>。参数的数量由<code>arguments.length</code>表示。</p>
<p>使用 arguments 对象，你可以处理比声明的更多的参数来调用函数。这在你事先不知道会需要将多少参数传递给函数时十分有用。你可以用<code>arguments.length</code>来获得实际传递给函数的参数的数量，然后用<code>arguments</code>对象来取得每个参数。</p>
<p>例如，设想有一个用来连接字符串的函数。唯一事先确定的参数是在连接后的字符串中用来分隔各个连接部分的字符（译注：比如例子里的分号“；”）。该函数定义如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">myConcat</span>(<span class="params">separator</span>) &#123;</span><br><span class="line">   <span class="keyword">var</span> result = <span class="string">&#x27;&#x27;</span>; <span class="comment">// 把值初始化成一个字符串，这样就可以用来保存字符串了！！</span></span><br><span class="line">   <span class="keyword">var</span> i;</span><br><span class="line">   <span class="comment">// iterate through arguments</span></span><br><span class="line">   <span class="keyword">for</span> (i = <span class="number">1</span>; i &lt; <span class="variable language_">arguments</span>.<span class="property">length</span>; i++) &#123;</span><br><span class="line">      result += <span class="variable language_">arguments</span>[i] + separator;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>你可以给这个函数传递任意数量的参数，它会将各个参数连接成一个字符串“列表”：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// returns &quot;red, orange, blue, &quot;</span></span><br><span class="line"><span class="title function_">myConcat</span>(<span class="string">&quot;, &quot;</span>, <span class="string">&quot;red&quot;</span>, <span class="string">&quot;orange&quot;</span>, <span class="string">&quot;blue&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// returns &quot;elephant; giraffe; lion; cheetah; &quot;</span></span><br><span class="line"><span class="title function_">myConcat</span>(<span class="string">&quot;; &quot;</span>, <span class="string">&quot;elephant&quot;</span>, <span class="string">&quot;giraffe&quot;</span>, <span class="string">&quot;lion&quot;</span>, <span class="string">&quot;cheetah&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// returns &quot;sage. basil. oregano. pepper. parsley. &quot;</span></span><br><span class="line"><span class="title function_">myConcat</span>(<span class="string">&quot;. &quot;</span>, <span class="string">&quot;sage&quot;</span>, <span class="string">&quot;basil&quot;</span>, <span class="string">&quot;oregano&quot;</span>, <span class="string">&quot;pepper&quot;</span>, <span class="string">&quot;parsley&quot;</span>);</span><br></pre></td></tr></table></figure>

<p><strong>备注：</strong> <code>arguments</code> 变量只是“<strong>类数组对象</strong>”，并不是一个数组。称其为类数组对象是说它有一个索引编号和<code>length</code>属性。尽管如此，它并不拥有全部的 Array 对象的操作方法。</p>
<p>更多信息请阅读 JavaScript 参考里的<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function"><code>Function</code></a>一文。</p>
<h2 id="函数参数"><a href="#函数参数" class="headerlink" title="函数参数"></a>函数参数</h2><p>从 ECMAScript 6 开始，有两个新的类型的参数：默认参数，剩余参数。</p>
<h3 id="默认参数"><a href="#默认参数" class="headerlink" title="默认参数"></a>默认参数</h3><p>在 JavaScript 中，函数参数的默认值是<code>undefined</code>。然而，在某些情况下设置不同的默认值是有用的。这时默认参数可以提供帮助。</p>
<p>在过去，用于设定默认参数的一般策略是在函数的主体中测试参数值是否为<code>undefined</code>，如果是则赋予这个参数一个默认值。如果在下面的例子中，调用函数时没有实参传递给<code>b</code>，那么它的值就是<code>undefined</code>，于是计算<code>a*b</code>得到、函数返回的是 <code>NaN</code>。但是，在下面的例子中，这个已经被第二行获取处理：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">multiply</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  b = (<span class="keyword">typeof</span> b !== <span class="string">&#x27;undefined&#x27;</span>) ?  b : <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> a*b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">multiply</span>(<span class="number">5</span>); <span class="comment">// 5</span></span><br></pre></td></tr></table></figure>

<p>使用默认参数，在函数体的检查就不再需要了。现在，你可以在函数头简单地把 1 设定为<code>b</code>的默认值：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">multiply</span>(<span class="params">a, b = <span class="number">1</span></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a*b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">multiply</span>(<span class="number">5</span>); <span class="comment">// 5</span></span><br></pre></td></tr></table></figure>

<p>了解更多<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Default_parameters">默认参数</a>的信息。</p>
<h3 id="剩余参数"><a href="#剩余参数" class="headerlink" title="剩余参数"></a>剩余参数</h3><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/rest_parameters">剩余参数</a>语法允许将不确定数量的参数表示为数组。在下面的例子中，使用剩余参数收集从第二个到最后参数。然后，我们将这个数组的每一个数与第一个参数相乘。这个例子是使用了一个箭头函数，这将在下一节介绍。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">multiply</span>(<span class="params">multiplier, ...theArgs</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> theArgs.<span class="title function_">map</span>(<span class="function"><span class="params">x</span> =&gt;</span> multiplier * x);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr = <span class="title function_">multiply</span>(<span class="number">2</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr); <span class="comment">// [2, 4, 6]</span></span><br></pre></td></tr></table></figure>

<h2 id="箭头函数-notebook"><a href="#箭头函数-notebook" class="headerlink" title="箭头函数:notebook:"></a>箭头函数:notebook:</h2><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数表达式</a>（也称胖箭头函数）相比函数表达式具有较短的语法并以词法的方式绑定 <code>this</code>。箭头函数总是匿名的。另见 hacks.mozilla.org 的博文：“<a target="_blank" rel="noopener" href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">深度了解 ES6：箭头函数</a>”。</p>
<p>有两个因素会影响引入箭头函数：更简洁的函数和 <code>this</code>。</p>
<h3 id="更简洁的函数"><a href="#更简洁的函数" class="headerlink" title="更简洁的函数"></a>更简洁的函数</h3><p>在一些函数模式中，更简洁的函数很受欢迎。对比一下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = [</span><br><span class="line">  <span class="string">&quot;Hydrogen&quot;</span>,</span><br><span class="line">  <span class="string">&quot;Helium&quot;</span>,</span><br><span class="line">  <span class="string">&quot;Lithium&quot;</span>,</span><br><span class="line">  <span class="string">&quot;Beryllium&quot;</span></span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a2 = a.<span class="title function_">map</span>(<span class="keyword">function</span>(<span class="params">s</span>)&#123; <span class="keyword">return</span> s.<span class="property">length</span> &#125;);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a2); <span class="comment">// logs [ 8, 6, 7, 9 ]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a3 = a.<span class="title function_">map</span>( <span class="function"><span class="params">s</span> =&gt;</span> s.<span class="property">length</span> );</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a3); <span class="comment">// logs [ 8, 6, 7, 9 ]</span></span><br></pre></td></tr></table></figure>

<h3 id="this-的词法"><a href="#this-的词法" class="headerlink" title="this 的词法"></a><code>this</code> 的词法</h3><p>在箭头函数出现之前，每一个新函数都重新定义了自己的 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this">this</a> 值（在构造函数中是一个新的对象；在严格模式下是未定义的；在作为“对象方法”调用的函数中指向这个对象；等等）。以面向对象的编程风格，这样着实有点恼人。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">// 构造函数 Person() 将`this`定义为自身</span></span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">setInterval</span>(<span class="keyword">function</span> <span class="title function_">growUp</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// 在非严格模式下，growUp() 函数将`this`定义为“全局对象”，</span></span><br><span class="line">    <span class="comment">// 这与 Person() 定义的`this`不同，</span></span><br><span class="line">    <span class="comment">// 所以下面的语句不会起到预期的效果。</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span>++;</span><br><span class="line">  &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br></pre></td></tr></table></figure>

<p>在 ECMAScript 3&#x2F;5 里，通过把<code>this</code>的值赋值给一个变量可以修复这个问题。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> self = <span class="variable language_">this</span>; <span class="comment">// 有的人习惯用`that`而不是`self`，</span></span><br><span class="line">                   <span class="comment">// 无论你选择哪一种方式，请保持前后代码的一致性</span></span><br><span class="line">  self.<span class="property">age</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">setInterval</span>(<span class="keyword">function</span> <span class="title function_">growUp</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// 以下语句可以实现预期的功能</span></span><br><span class="line">    self.<span class="property">age</span>++;</span><br><span class="line">  &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>另外，创建一个<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">约束函数</a>可以使得 <code>this</code>值被正确传递给 <code>growUp()</code> 函数。</p>
<p>箭头函数捕捉闭包上下文的<code>this</code>值，所以下面的代码工作正常。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">setInterval</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span>++; <span class="comment">// 这里的`this`正确地指向 person 对象</span></span><br><span class="line">  &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br></pre></td></tr></table></figure>

<h2 id="预定义函数"><a href="#预定义函数" class="headerlink" title="预定义函数"></a>预定义函数</h2><p>JavaScript 语言有好些个顶级的内建函数：</p>
<ul>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval"><code>eval()</code></a></p>
<p><strong><code>eval()</code></strong> 方法会对一串字符串形式的 JavaScript 代码字符求值。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects"><code>uneval()</code></a> 非标准</p>
<p><strong><code>uneval()</code></strong> 方法创建的一个 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object"><code>Object</code></a> 的源代码的字符串表示。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isFinite"><code>isFinite()</code></a></p>
<p><strong><code>isFinite()</code></strong> 函数判断传入的值是否是有限的数值。如果需要的话，其参数首先被转换为一个数值。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isNaN"><code>isNaN()</code></a></p>
<p><strong><code>isNaN()</code></strong> 函数判断一个值是否是 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>。注意：<code>isNaN</code> 函数内部的<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isNaN#%E6%8F%8F%E8%BF%B0">强制转换规则</a>十分有趣；另一个可供选择的是 ECMAScript 6 中定义 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN"><code>Number.isNaN()</code></a>, 或者使用 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof"><code>typeof</code></a> 来判断数值类型。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseFloat"><code>parseFloat()</code></a></p>
<p><strong><code>parseFloat()</code></strong> 函数解析字符串参数，并返回一个浮点数。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt"><code>parseInt()</code></a></p>
<p><strong><code>parseInt()</code></strong> 函数解析字符串参数，并返回指定的基数（基础数学中的数制）的整数。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI"><code>decodeURI()</code></a></p>
<p><strong><code>decodeURI()</code></strong> 函数对先前经过 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI"><code>encodeURI</code></a> 函数或者其他类似方法编码过的字符串进行解码。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent"><code>decodeURIComponent()</code></a></p>
<p><strong><code>decodeURIComponent()</code></strong> 方法对先前经过 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent"><code>encodeURIComponent</code></a> 函数或者其他类似方法编码过的字符串进行解码。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI"><code>encodeURI()</code></a></p>
<p><strong><code>encodeURI()</code></strong> 方法通过用以一个、两个、三个或四个转义序列表示字符的 UTF-8 编码替换统一资源标识符（URI）的某些字符来进行编码（每个字符对应四个转义序列，这四个序列组了两个”替代“字符）。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent"><code>encodeURIComponent()</code></a></p>
<p><strong><code>encodeURIComponent()</code></strong> 方法通过用以一个，两个，三个或四个转义序列表示字符的 UTF-8 编码替换统一资源标识符（URI）的每个字符来进行编码（每个字符对应四个转义序列，这四个序列组了两个”替代“字符）。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/escape"><code>escape()</code></a> 已弃用</p>
<p>已废弃的 <strong><code>escape()</code></strong> 方法计算生成一个新的字符串，其中的某些字符已被替换为十六进制转义序列。使用 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI"><code>encodeURI</code></a>或者<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent"><code>encodeURIComponent</code></a>替代本方法。</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/unescape"><code>unescape()</code></a> 已弃用</p>
<p>已废弃的 <strong><code>unescape()</code></strong> 方法计算生成一个新的字符串，其中的十六进制转义序列将被其表示的字符替换。上述的转义序列就像<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/escape"><code>escape</code></a>里介绍的一样。因为 <code>unescape</code> 已经废弃，建议使用<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI"><code>decodeURI()</code></a>或者<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent"><code>decodeURIComponent</code></a> 替代本方法。</p>
</li>
</ul>
<hr>

        
            <div class="donate-container">
    <div class="donate-button">
        <button id="donate-button">赞赏</button>
    </div>
    <div class="donate-img-container hide" id="donate-img-container">
        <img id="donate-img" src="" data-src="/myblog/img/donate.jpg">
        <p> 感谢鼓励 </p>
    </div>
</div>
        
        <br />
        <div id="comment-container">
        </div>
        <div id="disqus_thread"></div>
        <div id="lv-container"></div>
        <div class="giscus"></div>
    </div>
</div>

    </div>
</div>


<footer class="footer">
    <ul class="list-inline text-center">
        
        

        

        

        
        <li>
            <a target="_blank"  href="https://github.com/samuel-24276">
                            <span class="fa-stack fa-lg">
                                <i class="iconfont icon-github"></i>
                            </span>
            </a>
        </li>
        

        

    </ul>
    
    <p>
        <span>/</span>
        
        <span><a target="_blank" rel="noopener" href="https://github.com/samuel-24276">samuel-24276&#39;s Page</a></span>
        <span>/</span>
        
        <span><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/">北京-未备案</a></span>
        <span>/</span>
        
        <span><a href="#">返回顶部</a></span>
        <span>/</span>
        
    </p>
    
    <p>
        <span id="busuanzi_container_site_pv">
            <span id="busuanzi_value_site_pv"></span>PV
        </span>
        <span id="busuanzi_container_site_uv">
            <span id="busuanzi_value_site_uv"></span>UV
        </span>
        Created By <a target="_blank" rel="noopener" href="https://hexo.io/">Hexo</a>  Theme <a target="_blank" rel="noopener" href="https://github.com/aircloud/hexo-theme-aircloud">AirCloud</a></p>
</footer>




</body>

<script>
    // We expose some of the variables needed by the front end
    window.hexo_search_path = "search.json"
    window.hexo_root = "/myblog/"
    window.isPost = true
</script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

<script src="/myblog/js/index.js"></script>

<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>






    <script type="text/javascript">
       (function() {
           if (typeof LivereTower === 'function') { return; }

           var j, d = document.getElementById('lv-container');

           d.setAttribute('data-id','city');
           d.setAttribute('data-uid' , 'MTAyMC80OTA5OC8yNTU5Mw==');

           j = document.createElement('script');
           j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
           j.async = true;

           d.appendChild(j);
       })();
    </script>
    <noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
    </div>

</html>
